package cn.com.fssg.platform.base.handler.impl.gsl.lz;

import cn.com.fssg.platform.base.handler.InterfaceHandler;
import cn.com.fssg.platform.biz.BizUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoField;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description: 工商联履职考核提交接口
 */
@Component
public class GslLzAssSaveCtl implements InterfaceHandler {

    private NamedParameterJdbcTemplate jdbcTemplate = BizUtil.cur().tenantMainJdbcTemplate();

//    @Autowired
//    private NamedParameterJdbcTemplate jdbcTemplate;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object run(HttpServletRequest request, JSONObject jsonObject) throws Exception {
        //获取考核项信息-gsl_assessment_subject
        String querySubjectSql = "select * from gsl_assessment_subject where id = :id and del_flag = '0'";
        Map<String, Object> querySubjectParam = new HashMap<>();
        querySubjectParam.put("id", jsonObject.get("ass_id"));
        List<Map<String, Object>> abList = jdbcTemplate.queryForList(querySubjectSql, querySubjectParam);
        if(abList.isEmpty()) {
            return "该考核项不存在，请刷新页面后重试";
        }
        Map<String, Object> ab = abList.get(0);
        //获取考核表信息
        String queryAssSql = "select * from gsl_assessment where id = :id and del_flag = '0'";
        Map<String, Object> queryAssParam = new HashMap<>();
        queryAssParam.put("id", jsonObject.get("assessment_id"));
        List<Map<String, Object>> assList = jdbcTemplate.queryForList(queryAssSql, queryAssParam);
        if(assList.isEmpty()) {
            return "该考核项表不存在";
        }
        Map<String, Object> assessment = assList.get(0);
        if (Objects.equals(assessment.get("state"), "-1")) {
            return "抱歉，该考核表是新考核表，还未发布过，请发布！";
        }
        ab.put("audit_state", "1");
        Map<String, Object> ac = new HashMap<>();
        String acId = jsonObject.getString("id");
        ac.put("id", acId);
        //如果是管理员录入，那么必定要带回执委的id，如果不是管理员就用另外一个id
        String editUserId = BizUtil.cur().curUserId();
        boolean isZw = BizUtil.cur().curUserRoleContain("002");
        if(!isZw) {
            //不是执委登录，证明是管理员登录
            editUserId = jsonObject.getString("zw_id");
        }
        ac.put("create_by", editUserId);
        ac.put("update_by", editUserId);
        ac.put("create_date", new Date());
        ac.put("update_date", new Date());
        ac.put("del_flag", "0");

        ac.put("assessment_subject_id", jsonObject.get("assessment_subject_id"));
        ac.put("content", jsonObject.get("content"));
        ac.put("assessment_id", ab.get("assessment_id"));
        ac.put("audit_state", "0");

        //插入角色标识
        ac.put("role_scope", "1");
        ac.put("parent_role_scope", "1");

        //代表管理员提交的记录，自动审核通过
        if (!isZw) {
            ac.put("audit_state", "1");
            ac.put("audit_info", "您已通过审核");
            ac.put("audit_sc", "1");
            ac.put("audit_user_id", BizUtil.cur().curUserId());
            ac.put("audit_date", new Date());
        } else {
            if (!Objects.equals(assessment.get("state"), "1")) {
                return "抱歉，该考核表已结束";
            }
            String endDate = assessment.get("end_date").toString();
            LocalDate localDate = parseToLocalDate(endDate);
            if (localDate.isBefore(LocalDate.now())) {
                return "抱歉，该考核表已结束";
            }
        }
        //获取文件信息
        JSONArray jsonArray = jsonObject.getJSONArray("file_imgs");
        saveWxFile(jsonArray, acId, "image");
        JSONArray jsonArray2 = jsonObject.getJSONArray("file_Urls");
        saveWxFile(jsonArray2, acId, "file");
        saveConentAndWxFile(ac);
        updateDatabase(ab, "gsl_assessment_subject");
        return null;
    }

    public void saveConentAndWxFile(Map<String, Object> ac) {
//        if (wxFile.size() > 0) {
//            betch.batchInsert(wxFile);
//        }
        if (Objects.equals(ac.get("audit_sc"), "1")) {
            //获取考核项信息
            String queryAssSql = "select * from gsl_assessment where id = :id and del_flag = '0'";
            Map<String, Object> queryAssParam = new HashMap<>();
            queryAssParam.put("id", ac.get("assessment_id"));
            List<Map<String, Object>> assList = jdbcTemplate.queryForList(queryAssSql, queryAssParam);
            if (!assList.isEmpty()) {
                Map<String, Object> assessment = assList.get(0);
                //year1如何等于year2就表示是今年的审核内容，那么就添加到fslist
                DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                        .appendPattern("yyyy-MM-dd HH:mm:ss")
                        .appendFraction(ChronoField.MILLI_OF_SECOND, 1, 3, true) // 处理毫秒部分
                        .toFormatter();

                // 解析为 LocalDateTime
                LocalDateTime localDateTime = LocalDateTime.parse(assessment.get("create_date").toString(), formatter);
                Date date = Date.from(localDateTime.atZone(java.time.ZoneId.systemDefault()).toInstant());
                String year1 = getDateString(date, "yyyy");
                String year2 = getDateString(new Date(), "yyyy");
                if (StringUtils.equals(year1, year2)) {
                    Date start = getCurrYearFirst();
                    Date end = getCurrYearLast();

                    String queryAssContentSql = "select * from gsl_assessment_content where create_by = :create_by and audit_sc = '1' and create_date between :start and :end";
                    Map<String, Object> queryAssContentParam = new HashMap<>();
                    queryAssContentParam.put("create_by", ac.get("create_by"));
                    queryAssContentParam.put("start", start);
                    queryAssContentParam.put("end", end);
                    List<Map<String, Object>> fsList = jdbcTemplate.queryForList(queryAssContentSql, queryAssContentParam);

                    final Integer[] all = {0};
                    if (!fsList.isEmpty()) {
                        if (Objects.equals(ac.get("audit_sc"), "1")) {
                            fsList.add(ac);
                        }
                        String queryZwSql = "select * from zw_info where id = :id";
                        Map<String, Object> queryZwParam = new HashMap<>();
                        queryZwParam.put("id", ac.get("create_by"));
                        List<Map<String, Object>> zwInfoList = jdbcTemplate.queryForList(queryZwSql, queryZwParam);
                        if (!zwInfoList.isEmpty()) {
                            Map<String, Object> zwInfo = zwInfoList.get(0);
                            if (Objects.equals(zwInfo.get("is_cadre"), "1")) {
                                Map<String, Map<String, Object>> map = fsList.stream()
                                        .collect(Collectors.toMap(
                                                m -> {
                                                    Object id = m.get("assessment_subject_id");
                                                    return id != null ? id.toString() : "null";
                                                },
                                                Function.identity(),
                                                (existing, replacement) -> existing // 合并策略
                                        ));
                                map.forEach((k, v) -> {
                                    String queryAssSubSql = "select * from gsl_assessment_subject where id = :id";
                                    Map<String, Object> queryAssSubParam = new HashMap<>();
                                    queryAssSubParam.put("id", v.get("assessment_subject_id"));
                                    List<Map<String, Object>> assessmentSubjectList = jdbcTemplate.queryForList(queryAssSubSql, queryAssSubParam);
                                    if (!assessmentSubjectList.isEmpty()) {
                                        Map<String, Object> data = assessmentSubjectList.get(0);
                                        all[0] = (all[0] + Integer.parseInt(data.get("subject_fraction").toString()));
                                    }
                                    Map<String, Object> data = new HashMap<>();
                                    data.put("id", BizUtil.cur().getSnowflakeIdStr());
                                    data.put("zw_id", ac.get("create_by"));
                                    data.put("create_by", ac.get("create_by"));
                                    data.put("update_by", ac.get("create_by"));
                                    data.put("create_date", new Date());
                                    data.put("update_date", new Date());
                                    data.put("del_flag", "0");
//
                                    String queryWxUserSql = "select * from wx_user where id = :id";
                                    Map<String, Object> queryWxUserParam = new HashMap<>();
                                    queryWxUserParam.put("id", ac.get("create_by"));
                                    List<Map<String, Object>> wxUserList = jdbcTemplate.queryForList(queryWxUserSql, queryWxUserParam);
                                    if (!wxUserList.isEmpty()) {
                                        Map<String, Object> wxUser = wxUserList.get(0);
                                        data.put("phone", wxUser.get("phone"));
                                        data.put("zw_name", wxUser.get("username"));
                                    }
                                    data.put("set_fraction", String.valueOf(all[0]));
                                    insertDatabase(data, "gsl_topten");
                                });
                            }
                        }
                    }
                }
            }
        }

        Map<String, Object> save = new HashMap<>();
        save.put("id", BizUtil.cur().getSnowflakeIdStr());
        save.put("subject_id", ac.get("assessment_subject_id"));
        save.put("state", "1");
        save.put("create_by", ac.get("create_by"));
        save.put("update_by", ac.get("create_by"));
        save.put("create_date", new Date());;
        save.put("update_date", new Date());
        save.put("del_flag", "0");
        save.put("zw_id", ac.get("create_by"));
        insertDatabase(save, "gsl_subject_state");

        insertDatabase(ac, "gsl_assessment_content");
    }

    public void saveWxFile(JSONArray wxFiles, String acId, String type) {
        if(wxFiles != null && !wxFiles.isEmpty()) {
            wxFiles.forEach(wxFile -> {
               Map<String, Object> wxFileMap = (Map<String, Object>) wxFile;
               Map<String, Object> wxInsertMap = new HashMap<>();
               wxInsertMap.put("id", wxFileMap.get("id"));
               wxInsertMap.put("remark_id", acId);
               wxInsertMap.put("display_name", wxFileMap.get("fileName"));
               wxInsertMap.put("real_name", wxFileMap.get("aliasName"));
               wxInsertMap.put("path", wxFileMap.get("filePath"));
               wxInsertMap.put("type", type);

               wxInsertMap.put("del_flag", "0");
               wxInsertMap.put("update_by", wxFileMap.get("userId"));
               wxInsertMap.put("update_date", wxFileMap.get("modifyTime"));

               //验证是否存在当前ID
                String querySql2 = "select * from wx_file where id = :id";
                Map<String, Object> queryParam2 = new HashMap<>();
                queryParam2.put("id", wxInsertMap.get("id"));
                List<Map<String, Object>> fileList = jdbcTemplate.queryForList(querySql2, queryParam2);
                if (fileList.isEmpty()) {
                    wxInsertMap.put("create_by", wxFileMap.get("userId"));
                    wxInsertMap.put("create_date", wxFileMap.get("createTime"));
                    insertDatabase(wxInsertMap, "wx_file");
                } else {
                    updateDatabase(wxInsertMap, "wx_file");
                }

            });
        }

    }

    /** 更新数据库数据 */
    public int updateDatabase(Map<String, Object> param, String tableName) {
        List<String> fields = new ArrayList<>();
        param.forEach((k, v) -> {
            if (v != null && !"id".equals(k)) {
                fields.add(k + " = :" + k);
            }
        });

        String sql = String.format("UPDATE %s SET %s WHERE id = '%s'",
                tableName,
                String.join(", ", fields),
                param.get("id")
        );
        return jdbcTemplate.update(sql, param);
    }

    /** 新增数据库数据 */
    public int insertDatabase(Map<String, Object> param, String tableName) {
        List<String> fields = new ArrayList<>();
        List<String> placeholders = new ArrayList<>();
        param.forEach((k, v) -> {
            if (v != null) {
                fields.add(k);
                placeholders.add(":" + k);
            }
        });

        String sql = String.format("INSERT INTO %s (%s) VALUES (%s)",
                tableName,
                String.join(", ", fields),
                String.join(", ", placeholders)
        );
        return jdbcTemplate.update(sql, param);
    }

    public static Date getCurrYearFirst() {
        Calendar currCal = Calendar.getInstance();
        int currentYear = currCal.get(Calendar.YEAR);
        return getYearFirst(currentYear);
    }

    public static Date getYearFirst(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        Date currYearFirst = calendar.getTime();
        return currYearFirst;
    }

    public static Date getCurrYearLast() {
        Calendar currCal = Calendar.getInstance();
        int currentYear = currCal.get(Calendar.YEAR);
        return getYearLast(currentYear);
    }

    public static Date getYearLast(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        Date currYearLast = calendar.getTime();
        return currYearLast;
    }

    public static String getDateString(Date date, String formt) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(formt);

        return simpleDateFormat.format(date);
    }

    // 定义两种可能的格式
    public static final DateTimeFormatter[] FORMATTERS = {
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S"), // 带毫秒
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"), // 带毫秒
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")     // 不带毫秒
    };

    public static LocalDate parseToLocalDate(String dateTimeStr) {
        for (DateTimeFormatter formatter : FORMATTERS) {
            try {
                // 尝试用每种格式解析，成功则返回
                LocalDateTime localDateTime = LocalDateTime.parse(dateTimeStr, formatter);
                return localDateTime.toLocalDate();
            } catch (DateTimeParseException ignored) {
                // 忽略错误，继续尝试下一种格式
            }
        }
        throw new IllegalArgumentException("无法解析的日期格式: " + dateTimeStr);
    }
}